<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>天地图加载GeoServer WMS</title>
    <script src="/Public/js/tianditu.api.js"></script>
    <script src="/Public/js/jquery-3.7.1.min.js"></script>
    <script src="/Public/js/geotiff.js"></script>
    <script src="/Public/js/geoTools.js"></script>
    <script src="/Public/js/three.min.js"></script>
    <script src="/Public/js/OrbitControls.js"></script>
    <script src="/Public/js/geotiff.js"></script>
    <script src="/Public/js/three_shaders.js"></script>
    <link rel="icon" href="/Public/imgs/H.ico">
    <style>
        #map {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 100%;
            height: 100%;
        }

        #treeCon {
            position: absolute;
            top: 20px;
            right: 300px;
            width: 300px;
            height: 300px;
            background-color: rgba(136, 147, 161, 0.3);
            z-index: 450;
        }

        #btn1 {
            position: absolute;
            bottom: 100px;
            left: 20px;
            z-index: 450;
            width: 50px;
            height: 200x;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <button id="btn1">T</button>
    <div id="treeCon"></div>
    <script>
        let terrainMesh = null;
        let Three = window.Three
        const smoothness = 0.5
        const heightScale = 3.0
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x1a1a2e);

        const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10000);
        camera.position.set(1, 2, 3);
        const container = $('#treeCon')
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(container[0].clientWidth, container[0].clientHeight);
        container[0].appendChild(renderer.domElement);
        const ambientLight = new THREE.AmbientLight(0x404040);
        scene.add(ambientLight);
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(1, 1, 1);
        scene.add(directionalLight);
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;

        function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        }
        animate();
        var map = new T.Map('map', { tileSize: 512 });
        // map.centerAndZoom(new T.LngLat(103, 30), 15);
        map.centerAndZoom(new T.LngLat(99.4, 30.3), 15);


        var wmsLayer = new T.TileLayer.WMS(
            'http://localhost:8080/geoserver/WMTS_DEM/wms',
            {
                layers: 'WMTS_DEM:DEM_DQ_FW_PL',
                format: 'image/png',
                transparent: true,
                version: '1.1.1',
                srs: 'EPSG:4326',
                styles: '',
                exceptions: 'application/vnd.ogc.se_inimage'
            },
            {
                opacity: 0.7,
                minZoom: 0,
                maxZoom: 18
            }
        );
        // 添加WMS图层
        map.addLayer(wmsLayer);


        var recTool = new T.RectangleTool(map, { showLabel: false });;

        async function loadDEMFromGeoServer(file) {
            console.log(file)
            const arrayBuffer = await file.arrayBuffer();
            const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer);
            const image = await tiff.getImage();
            const rasters = await image.readRasters();

            const width = image.getWidth();
            const height = image.getHeight();

            let elevationData;
            if (rasters[0] instanceof Float32Array) {
                elevationData = rasters[0];
            } else if (rasters[0] instanceof Int16Array) {
                elevationData = new Float32Array(rasters[0]);
            } else {
                elevationData = new Float32Array(rasters[0]);
            }
            processElevationData(elevationData, width, height);
        }

        // 处理高程数据并创建地形网格
        function processElevationData(data, width, height) {
            if (terrainMesh) {
                scene.remove(terrainMesh);
                terrainMesh.geometry.dispose();
                terrainMesh.material.dispose();
            }

            const geometry = new THREE.PlaneGeometry(5, 5, width - 1, height - 1);
            const vertices = geometry.attributes.position.array;
            const maxElevation = Math.max(...data);
            const minElevation = Math.min(...data.filter(num => num !== 0))
            const n_data = data.map(num => num === 0 ? minElevation - 1 : num)

            const positions = geometry.attributes.position.array;
            for (let i = 0; i < data.length; i++) {
                positions[i * 3 + 2] = (data[i] - minElevation) / (maxElevation - minElevation); // 设置Z坐标
            }
            geometry.attributes.position.needsUpdate = true;
            geometry.computeVertexNormals();

            const colors = [];
            for (let i = 0, j = 0; i < vertices.length; i += 3, j++) {
                if (j < data.length) {
                    const elevation = (n_data[j] - minElevation) / (maxElevation - minElevation);
                    const color = new THREE.Color();
                    if (n_data[j] == minElevation - 1) {
                        color.setRGB(0, 0, 0);
                        colors.push(color.r, color.g, color.b);
                    } else {
                        color.setHSL(0.7 * (1 - elevation), 1, 0.5);
                        colors.push(color.r, color.g, color.b);
                    };
                }
            }
            geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
            // 创建材质
            const customShaderMaterial = new THREE.ShaderMaterial({
                uniforms: {
                    c_r: { value: 0.0 },
                    c_g: { value: 0.0 },
                    c_b: { value: 0.0 },
                    opacity: { value: 1.0 }
                },
                vertexShader: vs1,
                fragmentShader: fs2,
                vertexColors: true,
                transparent: true,
                side: THREE.DoubleSide
            });

            terrainMesh = new THREE.Mesh(geometry, customShaderMaterial);
            terrainMesh.rotation.x = -Math.PI / 2;
            scene.add(terrainMesh);
            camera.position.set(0, 2, 3);
            controls.reset();

        }

        $('#btn1').on('click', HD1)
        function HD1() {
            var dis
            recTool.removeEventListener('draw');
            recTool.clear();
            recTool.open();
            recTool.addEventListener('draw', (e) => {
                // var minX = e.currentBounds.getSouthWest().lng
                // var minY = e.currentBounds.getSouthWest().lat
                // var maxX = e.currentBounds.getNorthEast().lng
                // var maxY = e.currentBounds.getNorthEast().lat

                var minX = 99.3996095590388
                var minY = 30.3056429795424
                var maxX = 99.4011165003925
                var maxY = 30.30702434245

                var pro_p1 = LatLon2XY(minX, minY)
                var pro_p2 = LatLon2XY(maxX, maxY)

                var dom_width = Math.floor((pro_p2.y - pro_p1.y))
                var dom_height = Math.floor((pro_p2.x - pro_p1.x))

                var imageURL =
                    'http://localhost:8080/geoserver/WMTS_DEM/wms?' +
                    'Request=GetMap' +
                    '&Service=WMS' +
                    '&Version=1.1.0' +
                    '&LAYERS=WMTS_DEM%3Adem_dq_4326' +
                    '&STYLE=' +
                    '&BBOX=' + minX + '%2C' + minY + '%2C' + maxX + '%2C' + maxY +
                    '&WIDTH=' + dom_width +
                    '&HEIGHT=' + dom_height +
                    '&SRS=EPSG%3A4326' +
                    '&FORMAT=image%2Fgeotiff' +
                    '&TRANSPARENT=true'
                fetch(imageURL).then(res => {
                    loadDEMFromGeoServer(res)
                    // renderer.setSize(container[0].clientWidth, container[0].clientHeight);
                    // loadDEMFromGeoServer()
                })

                // var imageURL2 =
                //     'http://localhost:8080/geoserver/WMTS_DEM/wms?' +
                //     'Request=GetMap' +
                //     '&Service=WMS' +
                //     '&Version=1.1.0' +
                //     '&LAYERS=WMTS_DEM%3Adem_dq_4326' +
                //     '&STYLE=' +
                //     '&BBOX=' + minX + '%2C' + minY + '%2C' + maxX + '%2C' + maxY +
                //     '&WIDTH=' + dom_width +
                //     '&HEIGHT=' + dom_height +
                //     '&SRS=EPSG%3A4326' +
                //     '&FORMAT=image%2Fpng' +
                //     '&TRANSPARENT=true'
                // fetch(imageURL2)
            })


        }
    </script>
</body>

</html>